package convert

import (
	"encoding/json"
	"reflect"
	"strconv"
	"strings"
	"time"
)

// Int 转换为int类型
func Int(any interface{}) int {
	if any == nil {
		return 0
	}
	switch v := any.(type) {
	case int:
		return v
	case int8:
		return int(v)
	case int16:
		return int(v)
	case int32:
		return int(v)
	case int64:
		return int(v)
	case uint:
		return int(v)
	case uint8:
		return int(v)
	case uint16:
		return int(v)
	case uint32:
		return int(v)
	case uint64:
		return int(v)
	case float32:
		return int(v)
	case float64:
		return int(v)
	case bool:
		if v {
			return 1
		}
		return 0
	case string:
		if i, err := strconv.Atoi(v); err == nil {
			return i
		}
		if f, err := strconv.ParseFloat(v, 64); err == nil {
			return int(f)
		}
		if b, err := strconv.ParseBool(v); err == nil {
			if b {
				return 1
			}
			return 0
		}
		return 0
	case []byte:
		return Int(string(v))
	default:
		// 处理指针类型
		rv := reflect.ValueOf(any)
		for rv.Kind() == reflect.Ptr {
			rv = rv.Elem()
			if !rv.IsValid() {
				return 0
			}
			any = rv.Interface()
			return Int(any)
		}
		return 0
	}
}

// Int64 转换为int64类型
func Int64(any interface{}) int64 {
	if any == nil {
		return 0
	}
	switch v := any.(type) {
	case int64:
		return v
	case time.Duration:
		return int64(v)
	default:
		return int64(Int(any))
	}
}

// Float64 转换为float64类型
func Float64(any interface{}) float64 {
	if any == nil {
		return 0
	}
	switch v := any.(type) {
	case float64:
		return v
	case float32:
		return float64(v)
	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
		return float64(Int64(any))
	case bool:
		if v {
			return 1
		}
		return 0
	case string:
		if f, err := strconv.ParseFloat(v, 64); err == nil {
			return f
		}
		if i, err := strconv.ParseInt(v, 10, 64); err == nil {
			return float64(i)
		}
		if b, err := strconv.ParseBool(v); err == nil {
			if b {
				return 1
			}
			return 0
		}
		return 0
	case []byte:
		return Float64(string(v))
	default:
		// 处理指针类型
		rv := reflect.ValueOf(any)
		for rv.Kind() == reflect.Ptr {
			rv = rv.Elem()
			if !rv.IsValid() {
				return 0
			}
			any = rv.Interface()
			return Float64(any)
		}
		return 0
	}
}

// Bool 转换为bool类型
func Bool(any interface{}) bool {
	if any == nil {
		return false
	}
	switch v := any.(type) {
	case bool:
		return v
	case string:
		if strings.EqualFold(v, "true") {
			return true
		}
		if strings.EqualFold(v, "false") {
			return false
		}
		if i := Int(v); i != 0 {
			return true
		}
		return false
	case []byte:
		return Bool(string(v))
	default:
		if Int(any) != 0 {
			return true
		}
		return false
	}
}

// String 转换为string类型
func String(any interface{}) string {
	if any == nil {
		return ""
	}
	switch v := any.(type) {
	case string:
		return v
	case []byte:
		return string(v)
	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
		return strconv.FormatInt(Int64(any), 10)
	case float32, float64:
		return strconv.FormatFloat(Float64(any), 'f', -1, 64)
	case bool:
		return strconv.FormatBool(v)
	case time.Time:
		return v.String()
	case time.Duration:
		return v.String()
	default:
		// 处理指针类型
		rv := reflect.ValueOf(any)
		for rv.Kind() == reflect.Ptr {
			rv = rv.Elem()
			if !rv.IsValid() {
				return ""
			}
			any = rv.Interface()
			return String(any)
		}
		// 尝试JSON序列化
		if b, err := json.Marshal(any); err == nil {
			return string(b)
		}
		return ""
	}
}

// Bytes 转换为[]byte类型
func Bytes(any interface{}) []byte {
	if any == nil {
		return nil
	}
	switch v := any.(type) {
	case []byte:
		return v
	case string:
		return []byte(v)
	default:
		return []byte(String(any))
	}
}

// Time 转换为time.Time类型
func Time(any interface{}, format ...string) time.Time {
	if any == nil {
		return time.Time{}
	}

	var layout = "2006-01-02 15:04:05"
	if len(format) > 0 {
		layout = format[0]
	}

	switch v := any.(type) {
	case time.Time:
		return v
	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
		return time.Unix(Int64(any), 0)
	case float32, float64:
		return time.Unix(int64(Float64(any)), 0)
	case string:
		if t, err := time.Parse(layout, v); err == nil {
			return t
		}
		if i := Int64(v); i != 0 {
			return time.Unix(i, 0)
		}
		return time.Time{}
	case []byte:
		return Time(string(v), format...)
	default:
		return time.Time{}
	}
}

// Duration 转换为time.Duration类型
func Duration(any interface{}) time.Duration {
	if any == nil {
		return 0
	}
	switch v := any.(type) {
	case time.Duration:
		return v
	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
		return time.Duration(Int64(any))
	case float32, float64:
		return time.Duration(Float64(any))
	case string:
		if d, err := time.ParseDuration(v); err == nil {
			return d
		}
		if i := Int64(v); i != 0 {
			return time.Duration(i)
		}
		return 0
	case []byte:
		return Duration(string(v))
	default:
		return 0
	}
}

// Slice 转换为[]interface{}类型
func Slice(any interface{}) []interface{} {
	if any == nil {
		return nil
	}

	switch v := any.(type) {
	case []interface{}:
		return v
	case []string:
		var slice = make([]interface{}, len(v))
		for i, val := range v {
			slice[i] = val
		}
		return slice
	case []int:
		var slice = make([]interface{}, len(v))
		for i, val := range v {
			slice[i] = val
		}
		return slice
	case []float64:
		var slice = make([]interface{}, len(v))
		for i, val := range v {
			slice[i] = val
		}
		return slice
	case []bool:
		var slice = make([]interface{}, len(v))
		for i, val := range v {
			slice[i] = val
		}
		return slice
	default:
		// 处理指针类型
		rv := reflect.ValueOf(any)
		for rv.Kind() == reflect.Ptr {
			rv = rv.Elem()
			if !rv.IsValid() {
				return nil
			}
			any = rv.Interface()
			return Slice(any)
		}

		// 尝试JSON转换
		if b, err := json.Marshal(any); err == nil {
			var slice []interface{}
			if err := json.Unmarshal(b, &slice); err == nil {
				return slice
			}
		}

		// 处理数组和切片
		if rv.Kind() == reflect.Slice || rv.Kind() == reflect.Array {
			var slice = make([]interface{}, rv.Len())
			for i := 0; i < rv.Len(); i++ {
				slice[i] = rv.Index(i).Interface()
			}
			return slice
		}

		return nil
	}
}

// Map 转换为map[string]interface{}类型
func Map(any interface{}) map[string]interface{} {
	if any == nil {
		return nil
	}

	switch v := any.(type) {
	case map[string]interface{}:
		return v
	case map[interface{}]interface{}:
		m := make(map[string]interface{})
		for key, val := range v {
			m[String(key)] = val
		}
		return m
	default:
		// 处理指针类型
		rv := reflect.ValueOf(any)
		for rv.Kind() == reflect.Ptr {
			rv = rv.Elem()
			if !rv.IsValid() {
				return nil
			}
			any = rv.Interface()
			return Map(any)
		}

		// 尝试JSON转换
		if b, err := json.Marshal(any); err == nil {
			var m map[string]interface{}
			if err := json.Unmarshal(b, &m); err == nil {
				return m
			}
		}

		// 处理结构体
		if rv.Kind() == reflect.Struct {
			m := make(map[string]interface{})
			t := rv.Type()
			for i := 0; i < rv.NumField(); i++ {
				field := t.Field(i)
				// 只导出公开字段
				if field.PkgPath == "" {
					m[field.Name] = rv.Field(i).Interface()
				}
			}
			return m
		}

		return nil
	}
}

// Struct 将值转换为指定的结构体
func Struct(any interface{}, pointer interface{}) error {
	if any == nil || pointer == nil {
		return nil
	}

	// 获取指针的值
	rv := reflect.ValueOf(pointer)
	if rv.Kind() != reflect.Ptr || rv.IsNil() {
		return &json.InvalidUnmarshalError{Type: reflect.TypeOf(pointer)}
	}

	// 尝试JSON转换
	b, err := json.Marshal(any)
	if err != nil {
		return err
	}
	return json.Unmarshal(b, pointer)
}
